package com.panpass.idempotent.config;

import com.panpass.idempotent.aspect.IdempotentAspect;
import com.panpass.idempotent.utils.RedisHelper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * 幂等组件自动配置
 *
 * @author lw
 * @version 1.0.0
 */
@Configuration
@EnableConfigurationProperties(IdempotentProperties.class)
@ConditionalOnClass({StringRedisTemplate.class, RedisConnectionFactory.class})
@ConditionalOnProperty(prefix = "idempotent", name = "enabled", havingValue = "true", matchIfMissing = true)
@Order(Ordered.LOWEST_PRECEDENCE - 10)
public class IdempotentAutoConfiguration {

    /**
     * 配置Redis模板
     */
    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 配置Redis工具类
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(StringRedisTemplate.class)
    public RedisHelper redisHelper(StringRedisTemplate stringRedisTemplate) {
        return new RedisHelper(stringRedisTemplate);
    }

    /**
     * 配置幂等切面
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({RedisHelper.class})
    public IdempotentAspect idempotentAspect(
            RedisHelper redisHelper,
            IdempotentProperties properties) {
        return new IdempotentAspect(redisHelper, properties);
    }
}